#!/usr/bin/env python3
"""
生产环境配置验证脚本
用于验证.env配置是否正确，以及各项服务是否可用
"""

import os
import sys
from pathlib import Path
from dotenv import load_dotenv
import pymysql
import requests

def print_header(title):
    """打印标题"""
    print(f"\n{'='*60}")
    print(f" {title}")
    print(f"{'='*60}")

def print_status(item, status, details=""):
    """打印状态"""
    status_symbol = "✓" if status else "✗"
    color = "\033[92m" if status else "\033[91m"
    reset = "\033[0m"
    print(f"{color}{status_symbol}{reset} {item}")
    if details:
        print(f"  {details}")

def check_env_file():
    """检查.env文件配置"""
    print_header("环境配置文件检查")
    
    # 检查.env文件是否存在
    env_exists = Path(".env").exists()
    print_status(".env文件存在", env_exists)
    
    if not env_exists:
        return False
    
    # 加载环境变量
    load_dotenv()
    
    # 检查必要的配置项
    configs = [
        ("SECRET_KEY", "安全密钥"),
        ("JWT_SECRET_KEY", "JWT密钥"),
        ("DATABASE_URL", "数据库连接"),
        ("FLASK_ENV", "Flask环境"),
    ]
    
    all_good = True
    for key, name in configs:
        value = os.getenv(key)
        exists = bool(value)
        if key in ["SECRET_KEY", "JWT_SECRET_KEY"]:
            # 检查密钥长度
            length = len(value) if value else 0
            good_length = length >= 32
            print_status(f"{name}配置", exists and good_length, 
                        f"长度: {length} {'(推荐32+)' if length < 32 else '(良好)'}")
            all_good = all_good and exists and good_length
        else:
            print_status(f"{name}配置", exists, value[:50] + "..." if value and len(value) > 50 else value)
            all_good = all_good and exists
    
    return all_good

def check_directories():
    """检查必要目录"""
    print_header("目录结构检查")
    
    required_dirs = [
        "media",
        "logs", 
        "temp_uploads",
        "media/uploads",
        "media/exports",
        ".venv"
    ]
    
    all_good = True
    for dir_path in required_dirs:
        exists = Path(dir_path).exists()
        print_status(f"目录 {dir_path}", exists)
        all_good = all_good and exists
    
    return all_good

def check_database():
    """检查数据库连接"""
    print_header("数据库连接检查")
    
    database_url = os.getenv("DATABASE_URL")
    if not database_url:
        print_status("数据库配置", False, "DATABASE_URL未配置")
        return False
    
    try:
        # 解析数据库URL
        # mysql+pymysql://user:password@host:port/database
        import re
        match = re.match(r'mysql\+pymysql://([^:]+):([^@]+)@([^:]+):(\d+)/(.+)', database_url)
        if not match:
            print_status("数据库URL格式", False, "URL格式不正确")
            return False
        
        user, password, host, port, database = match.groups()
        
        # 测试连接
        connection = pymysql.connect(
            host=host,
            port=int(port),
            user=user,
            password=password,
            database=database,
            charset='utf8mb4'
        )
        
        cursor = connection.cursor()
        cursor.execute("SELECT VERSION()")
        version = cursor.fetchone()[0]
        cursor.close()
        connection.close()
        
        print_status("数据库连接", True, f"MySQL版本: {version}")
        return True
        
    except Exception as e:
        print_status("数据库连接", False, str(e))
        return False

def check_python_environment():
    """检查Python环境"""
    print_header("Python环境检查")
    
    # 检查Python版本
    version = f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"
    good_version = sys.version_info >= (3, 8)
    print_status(f"Python版本", good_version, f"当前版本: {version} {'(推荐3.8+)' if not good_version else '(良好)'}")
    
    # 检查关键包
    packages = [
        ("flask", "flask"),
        ("pymysql", "pymysql"), 
        ("python-dotenv", "dotenv"),  # 修正：python-dotenv的实际导入名是dotenv
        ("waitress", "waitress"),
        ("flask_migrate", "flask_migrate")
    ]
    
    all_packages = True
    for display_name, import_name in packages:
        try:
            __import__(import_name)
            print_status(f"包 {display_name}", True)
        except ImportError:
            print_status(f"包 {display_name}", False, "未安装")
            all_packages = False
    
    return good_version and all_packages

def check_service_ports():
    """检查服务端口"""
    print_header("服务端口检查")
    
    import socket
    
    ports_to_check = [
        (3306, "MySQL数据库"),
        (5000, "Flask应用"),
    ]
    
    all_good = True
    for port, service in ports_to_check:
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(3)
            result = sock.connect_ex(('localhost', port))
            sock.close()
            
            if result == 0:
                print_status(f"端口{port} ({service})", True, "端口可用")
            else:
                print_status(f"端口{port} ({service})", False, "端口不可达")
                if port == 3306:  # MySQL必须可用
                    all_good = False
        except Exception as e:
            print_status(f"端口{port} ({service})", False, str(e))
            if port == 3306:
                all_good = False
    
    return all_good

def generate_summary(results):
    """生成总结报告"""
    print_header("配置验证总结")
    
    all_passed = all(results.values())
    
    if all_passed:
        print("🎉 所有检查项均通过！生产环境配置正确。")
        print("\n建议下一步操作：")
        print("1. 运行生产服务器: .\\run_production_en.ps1")
        print("2. 访问 http://localhost:5000 验证服务")
    else:
        print("⚠️  存在配置问题，请根据上述检查结果进行修复。")
        print("\n需要修复的项目：")
        for item, passed in results.items():
            if not passed:
                print(f"- {item}")
    
    print(f"\n总体状态: {'通过' if all_passed else '失败'}")
    return all_passed

def main():
    """主函数"""
    print("DEV_VISION 生产环境配置验证工具")
    print("=" * 60)
    
    # 执行各项检查
    results = {
        "环境配置文件": check_env_file(),
        "目录结构": check_directories(), 
        "Python环境": check_python_environment(),
        "数据库连接": check_database(),
        "服务端口": check_service_ports(),
    }
    
    # 生成总结
    success = generate_summary(results)
    
    # 退出码
    sys.exit(0 if success else 1)

if __name__ == "__main__":
    main()
